import { KASEO_MAIN } from "../../../../KaseoApp";
import { Cmd2dDrawLine, Cmd2dDrawText, Cmd2dFillRect, Cmd2dPushFont, Cmd2dSetFillColor, Cmd2dSetStrokeColor, CMD_2D_CLEAR, CMD_2D_POP_STATE, CMD_2D_PUSH_STATE, Command2D, KaseoCommon2dGDI } from "../../dev/KaseoCanvasGraphicsDI";
import KaseoProgram from "../../KaseoProgram";
import { KaseoRuntimeBridge } from "../../KaseoRuntime";


const $BOOKS = [
    '『凉宫ハルヒの忧郁』',
    '『凉宫ハルヒの溜息』',
    '『凉宫ハルヒの退屈』',
    '『凉宫ハルヒの消失』',
    '『凉宫ハルヒの暴走』',
    '『凉宫ハルヒの动摇』',
    '『凉宫ハルヒの阴谋』',
    '『凉宫ハルヒの愤慨』',
    '『凉宫ハルヒの分裂』',
    '『凉宫ハルヒの惊愕(前)』',
    '『凉宫ハルヒの惊愕(後)』',
    '『涼宮ハルヒの直観』',
]


const PMGR_UI_TITLE_BAR_HEIGHT = 30
const PMGR_UI_PAGE_MAX_CONTAINS = 7
const PMGR_UI_PAGE_ITEM_HEIGHT = 26


type ListItem = {
    label: string
    index: number
}


export default class extends KaseoProgram {
    private ptrCur = 0
    private ptrBegin = 0

    private listItems: ListItem[] = []

    constructor() {
        super('progmgr')
    }
    
    private drawTitleBar(gdi: KaseoCommon2dGDI) {
        const width = gdi.getScreenWidth()

        const text = '应用程序'

        gdi.setContextFontStyle('1000')
        gdi.setContextFontSize(23)
        const mat = gdi.measureText(text)
        const [tw, th] = [mat.width, mat.actualBoundingBoxAscent]

        gdi.pushCommand2d(new Cmd2dPushFont())
        gdi.pushCommand2d(new Cmd2dSetFillColor(0, 0, 0))
        gdi.pushCommand2d(new Cmd2dSetStrokeColor(0, 0, 0))
        gdi.pushCommand2d(new Cmd2dDrawLine(0, PMGR_UI_TITLE_BAR_HEIGHT, width, PMGR_UI_TITLE_BAR_HEIGHT))

        gdi.pushCommand2d(new Cmd2dDrawText(
            text, width / 2 - tw / 2, PMGR_UI_TITLE_BAR_HEIGHT / 2 + th / 2 - 2))
    }

    private drawItemList(gdi: KaseoCommon2dGDI, list: ListItem[]) {
        const startY = PMGR_UI_TITLE_BAR_HEIGHT
        const width = gdi.getScreenWidth()

        const itemHeight = PMGR_UI_PAGE_ITEM_HEIGHT

        gdi.setContextFontSize(24)
        gdi.setContextFontStyle('1000')
        gdi.pushCommand2d(new Cmd2dPushFont())

        for (let i = 0;  i < PMGR_UI_PAGE_MAX_CONTAINS && i < list.length; ++i) {
            const item = list[i]

            if (item.index == this.ptrCur) {
                gdi.pushCommand2d(CMD_2D_PUSH_STATE)
                gdi.pushCommand2d(new Cmd2dSetFillColor(0, 0, 0))
                gdi.pushCommand2d(new Cmd2dFillRect(
                    0, (startY + itemHeight * i), width, itemHeight))
                gdi.pushCommand2d(new Cmd2dSetFillColor(1, 1, 1))
                gdi.pushCommand2d(new Cmd2dDrawText(
                    `${i + 1}: ${item.label}`, 2, (startY + itemHeight * i) + 23))
                gdi.pushCommand2d(CMD_2D_POP_STATE)
            } else {
                gdi.pushCommand2d(new Cmd2dDrawText(
                    `${i + 1}: ${item.label}`, 2, (startY + itemHeight * i) + 23))
            }
        }
    }

    private refreshUI(gdi: KaseoCommon2dGDI) {
        gdi.pushCommand2d(new Cmd2dSetFillColor(1, 1, 1))
        gdi.pushCommand2d(new Cmd2dFillRect(0, 0, 384, 216))
        this.drawTitleBar(gdi)

        this.drawItemList(gdi, this.getListToRender())
    }

    private refreshExUI(exGdi: KaseoCommon2dGDI) { 
        const text = 'KASEO'

        exGdi.setContextFontSize(70)
        exGdi.setContextFontStyle('1000')

        const mat = exGdi.measureText(text)
        
        const [w, h] = [exGdi.getScreenWidth(), exGdi.getScreenHeight()]
        const [tw, th] = [mat.width, mat.actualBoundingBoxAscent]

        exGdi.pushCommand2d(new Cmd2dSetFillColor(1, 1, 1))
        exGdi.pushCommand2d(new Cmd2dFillRect(0, 0, 260, 100))
        exGdi.pushCommand2d(new Cmd2dSetFillColor(0, 0, 0))
        exGdi.pushCommand2d(new Cmd2dDrawText(text, w / 2 - tw / 2, h / 2 + th / 2))
    }

    private getListToRender(): ListItem[] {
        const list: ListItem[] = []

        for (let i = this.ptrBegin, j = 0; 
                j < PMGR_UI_PAGE_MAX_CONTAINS && i < this.listItems.length; ++i, ++j) {
            
            list.push(this.listItems[i])
        }

        return list
    }

    private initProgramMenuList() {
        this.listItems = $BOOKS.map((val, idx) => { return {label: val, index: idx} })
    }
    
    onLaunch(bridge: KaseoRuntimeBridge): void {
        const gdi = bridge.getMajorGraphicsGDI()
        const exGdi = bridge.getExtraGraphicsGDI()

        if (gdi == null || exGdi == null)
            return

        this.initProgramMenuList()

        this.refreshUI(gdi)
        this.refreshExUI(exGdi)
    }

    execProgram() {
        const curProg = this.listItems[this.ptrCur]
        
    }

    onKnock(bridge: KaseoRuntimeBridge): void {
        const gdi = bridge.getMajorGraphicsGDI()
        const exGdi = bridge.getExtraGraphicsGDI()
        const kdi = bridge.getMajorKeyboardDI()
        if (kdi == null || gdi == null || exGdi == null)
            return

        let willingInc = 0

        if (kdi.getKeyDown(133)) willingInc = -1
        else if (kdi.getKeyDown(135)) willingInc = 1
        else return

        let ptrNew = this.ptrCur + willingInc

        if (ptrNew >= this.listItems.length)
            ptrNew = 0
        else if (ptrNew < 0)
            ptrNew = this.listItems.length - 1

        if (ptrNew == this.ptrCur)
            return

        this.ptrCur = ptrNew

        if (ptrNew < this.ptrBegin)
            this.ptrBegin = ptrNew
        else if (this.ptrBegin + PMGR_UI_PAGE_MAX_CONTAINS - 1 < ptrNew)
            this.ptrBegin = ptrNew - PMGR_UI_PAGE_MAX_CONTAINS + 1

        console.log(this.ptrCur)

        this.refreshUI(gdi)
        this.refreshExUI(exGdi)
    }
}
